最后更新时间:2019年7月4日
离线地图显示方法
离线地图数据类型包括离线矢量地图和离线瓦片地图,两种地图加载显示的方式也略有不同:
加载地图有多种方法,不同的方法适用于不同的数据类型,具有不同的应用场景。离线矢量地图、离线瓦片地图显示的核心方法如下表所示,从表中可以观察到,它们具有三种相同的方法,另外各自具有一种独有的方法,开发者可根据数据类型、实际需求来确定采用哪种方法。
方法 | 接口 | 地图类型 | 使用场景 |
---|---|---|---|
加载地图文档 | loadFromFile / loadFromFileAsync | 矢量 / 瓦片 | 最常用,适于地图文档中只有一个地图的情况,若有多个地图则默认加载第一个。 |
加载地图文档对应索引的地图 | loadFromDocument / loadFromDocumentAsync | 矢量 / 瓦片 | 适于加载有多个地图的地图文档,可控制加载某个地图。 |
通过地图文档获取Map | setMap / setMapAsync | 矢量 / 瓦片 | 适于加载地图之前需处理的情况,如删除部分图层、获取信息等。 |
通过数据库创建图层,从而构建Map | setMap / setMapAsync | 矢量 | 若获取到的数据只有“.mgdb”,无“.mapx”时,只能采用此方法。 |
基于ServerLayer实例化Map | setMap / setMapAsync | 瓦片 | 直接使用代加载瓦片地图,不用在桌面工具中配置地图文档。 |
一、加载地图文档
调用loadFromDocument / loadFromDocumentAsync方法加载地图文档,此方法是加载离线地图最常用、最简单的一种。前提是必须事先组织配置好mapx地图文档文件。
加载地图,采用MGSMapView作为地图容器,那么就首先需要引入下列头文件。
#import <MapGIS_Mobile_Map/mapview/MGSMapView.h>
可用代码方式构建MGSMapView控件,也可在StoryBoard故事板或xib中构建。构建完成后获取地图文档路径,调用loadFromDocument / loadFromDocumentAsync方法即可加载地图。核心代码如下:
#import "ShowDocVectorMap_ViewController.h" #import <MapGIS_Mobile_Map/mapview/MGSMapView.h> @interface ShowDocVectorMap_ViewController ()<MapViewDelegate> //定义地图视图控件对象 @property (weak, nonatomic) IBOutlet MGSMapView *mapView; @end @implementation ShowDocVectorMap_ViewController - (void)viewDidLoad { [super viewDidLoad]; //地图文档路径 NSString *mapPath=[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"/MapGIS Mobile 2D Sample/Map/MapShow/WuHan/WuHan.mapx"]; //同步方法 [_mapView loadFromFile:mapPath]; //设置代理 [_mapView setDelegate:self]; //异步方法 [_mapView loadFromFileAsync:offlineMapPath]; } @end
加载地图,根据实际需求选择同步方法或者异步方法。如果采用异步方法加载地图,可以利用MGSMapView的代理回调方法判断地图的加载情况,使用方法如下。
(1)使ViewController遵守MapViewDelegate地图控件代理协议:
@interface ShowDocVectorMap_ViewController ()<MapViewDelegate>
(2)为地图视图设置代理:
//设置代理 [_mapView setDelegate:self];
(3)然后实现代理的地图加载回调函数:
//开始加载地图监听 -(void)willStartLoadingMapWithMapView:(MGSMapView *)mapView strDocPath:(NSString *)strDocPath{ NSLog(@"开始加载地图"); } //加载地图完成事件监听 -(void)didFinishLoadingMapWithMapView:(MGSMapView *)mapView strDocPath:(NSString *)strDocPath{ NSLog(@"地图加载成功"); } //加载地图失败事件监听 -(void)didFailLoadingMapWithMapView:(MGSMapView *)mapView strDocPath:(NSString *)strDocPath{ NSLog(@"地图加载失败"); }
说明:缩放地图到某个范围或级别、添加覆盖物、地图要素查询编辑等地图操作,都需要在地图加载成功后才执行。
二、加载地图文档对应索引的地图
通过loadFromDocument / loadFromDocumentAsync来加载地图文档对应索引的地图,可以加载mapx地图文档中的指定地图,同样适用于离线矢量地图、离线瓦片地图。核心实现代码如下,在实现之前同样需要导入对应的头文件。
//定义地图视图控件、地图文档对象 @property (weak, nonatomic) IBOutlet MGSMapView *mapView; @property (nonatomic,strong) MGSDocument *document;
//地图文档路径 NSString *mapPath=[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"/MapGIS Mobile 2D Sample/Map/MapShow/WuHan/WuHan.mapx"]; _document=[[MGSDocument alloc] init]; //打开地图文档 [_document open:offlineMapPath]; //同步方法 [_mapView loadFromDocument:_document andIndex:0]; //异步方法 [_mapView loadFromDocumentAsync:_document andIndex:0 callback:^(BOOL success) { if (success) { //地图加载成功 } else { //地图加载失败 } }];
说明:在异步方法的回调函数中可判断地图的加载情况。
三、通过地图文档获取Map
通过地图文档MGSDocument获取MGSMap,调用setMap / setMapAsync方法加载地图。同样可以加载地图文档中指定的地图。
//定义地图视图、地图、地图文档对象 @property (weak, nonatomic) IBOutlet MGSMapView *mapView; @property (nonatomic,strong) MGSMap *map; @property (nonatomic,strong) MGSDocument *document;
//地图文档路径 NSString *mapPath=[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"/MapGIS Mobile 2D Sample/Map/MapShow/WuHan/WuHan.mapx"]; //创建文档对象 _document=[[MGSDocument alloc] init]; //打开地图文档 [_document open:mapPath]; //创建map,并获取地图文档中第一个地图 _map=[[MGSMap alloc] init]; _map=[[_document maps] getMapAtIndex:0]; //同步方法为地图视图设置地图对象 [_mapView setMap:_map]; //异步方法为地图视图设置地图对象 [_mapView setMapAsync:_map callback:^(BOOL success) { if (success) { //地图加载成功 } else { //地图加载失败 } }];
代码说明:利用setMap或setMapAsync将地图MGSMap赋予给地图视图MGSMapView时,MGSMap对象需定义为成员变量,从而实现生命周期的正确管理。
四、通过数据库创建图层构建Map
通过通过数据库MGSDataBase获取数据,创建图层,从而构建MGSMap,然后调用setMap / setMapAsync方法加载地图。此方法只适用于离线矢量数据,针对获取的数据中只有.mgdb数据库,无.mapx地图文档时。
//定义地图视图、地图、数据库对象 @property (weak, nonatomic) IBOutlet MGSMapView *mapView; @property (nonatomic,strong) MGSMap *map; @property (nonatomic,strong) MGSDataBase *dataBase;
//地图文档路径 NSString *dbPath=[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"/MapGIS Mobile 2D Sample/Map/MapShow/WuHan/武汉MKT.mgdb"]; //创建数据库对象 _dataBase=[[MGSDataBase alloc] init]; //打开数据库 [_dataBase open:offlineDataBasePath]; //创建地图对象 _map=[[MGSMap alloc] init]; if ([_dataBase hasOpened]) { //获取数据库中所有简单要素类的ID MGSIntList *intlist1=[_dataBase getXclseIDs:SFCls dsID:0]; //遍历简单要素类 for (int i=0; i<[intlist1 size]; i++) { //创建矢量图层 MGSVectorLayer *vectorLayer=[[MGSVectorLayer alloc] initWithType:SFClsLayer]; //根据id获取类信息 MGSFClsInfo *fclsInfo=[_dataBase getXclsInfoWithType:SFCls clsID:[intlist1 getAtIndex:i]]; //得到类信息,赋给vectorlayer [vectorLayer setUrl:[fclsInfo getURL]]; [vectorLayer setName:[fclsInfo getName]]; //为地图添加图层 [_map append:vectorLayer]; } //获取数据库中所有注记类的ID MGSIntList *intlist2=[_dataBase getXclseIDs:ACls dsID:0]; //遍历注记类 for (int i=0; i<[intlist2 size]; i++) { //创建矢量图层 MGSVectorLayer *vectorLayer=[[MGSVectorLayer alloc] initWithType:AnnLayer]; //根据id获取类信息 MGSFClsInfo *fclsInfo=[_dataBase getXclsInfoWithType:ACls clsID:[intlist2 getAtIndex:i]]; //得到类信息,赋给vectorlayer [vectorLayer setUrl:[fclsInfo getURL]]; [vectorLayer setName:[fclsInfo getName]]; //为地图添加图层 [_map append:vectorLayer]; } //为地图容器设置地图(同步方法) [_mapView setMap:_map]; //为地图容器设置地图(异步方法) [_mapView setMapAsync:_map callback:^(BOOL success) { if (success) { //地图加载成功 } else { //地图加载失败 } }]; } else { //数据库打开失败 }
五、基于ServerLayer实例化Map
通过服务图层MGSServerLayer实例化MGSMap,然后调用setMap / setMapAsync方法加载地图。离线瓦片地图能够采用此方法,不适用于离线矢量地图。此方法加载离线瓦片数据不用将其组织为地图文档,直接加载.TDF格式的瓦片数据文件即可。
//定义地图视图、地图 @property (weak, nonatomic) IBOutlet MGSMapView *mapView; @property (nonatomic,strong) MGSMap *map;
//获取本地瓦片地图路径 NSString *tilePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"/MapGIS Mobile 2D Sample/Map/MapShow/WorldMKTTile.TDF"]; //地图服务,根据MAPSERVER_TYPE_HDF类型创建 MGSMapServer* mapServer = [MGSServerLayer createMapServerByType:MAPSERVER_TYPE_HDF]; [mapServer setName:@"离线瓦片地图"]; [mapServer setUrl:tilePath]; //创建服务图层 MGSServerLayer *serverLayer=[[MGSServerLayer alloc] init]; [serverLayer setMapServer:mapServer]; //创建地图 _map=[[MGSMap alloc] init]; //为地图添加服务图层 [_map append:serverLayer]; //同步方法为地图容器设置地图 [_mapView setMap:_map]; //异步方法为地图容器设置地图 [_mapView setMapAsync:_map callback:^(BOOL success) { if (success) { //地图加载成功 } else { //地图加载失败 } }];
显示效果如下所示: